package com.dyzx.hbb.common.annotation;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dyzx.hbb.common.utils.BufferedRequestWrapper;
import com.dyzx.hbb.common.utils.SecurityUtils;
import com.dyzx.hbb.modules.sys.entity.SysLogOperation;
import com.dyzx.hbb.modules.sys.service.SysLogOperationService;

import org.aspectj.lang.Signature;
import org.springframework.security.core.context.SecurityContextHolder;
import com.dyzx.hbb.security.model.LoginUser;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;

import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Aspect
@Component
public class OperationLogAspect {

    @Autowired
    private SysLogOperationService operationService;

    @Value("${system.log.enable:true}")
    private boolean logEnabled;

    @Value("${system.log.ignore-get:true}")
    private boolean ignoreGetMethod;

    // 定义切点,拦截所有模块下的方法
    @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping) || @annotation(org.springframework.web.bind.annotation.PutMapping) || @annotation(org.springframework.web.bind.annotation.DeleteMapping)")
    public void pointcut() {
    }

    /**
     * 环绕通知，记录操作日志
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
   /*     if (!logEnabled) {
            return joinPoint.proceed();
        }
*/
        System.out.println("pointcut:1");
        long startTime = System.currentTimeMillis();
        System.out.println("pointcut:2");
        Object proceed = joinPoint.proceed();
        System.out.println("pointcut:3");
        long endTime = System.currentTimeMillis();
        System.out.println("pointcut:4");
        Signature signature = joinPoint.getSignature();

        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
            if (operationService != null && SecurityContextHolder.getContext().getAuthentication()!= null) {
                Object[] args = joinPoint.getArgs();
                LoginUser loginUser = SecurityUtils.getLoginUser();
                if (loginUser != null) {
                    asyncLogOperation(request, args);
                }

            }
        System.out.println("pointcut:5");

return proceed;

    }

    /**
     * 异步记录操作日志
     */
    @Async
    public CompletableFuture<Void> asyncLogOperation(HttpServletRequest request, Object[] args) {
        try {
            SysLogOperation operation = buildOperationLog(request,args);
           // operation.setExecutionTime(executionTime);
            operationService.save(operation);
            return CompletableFuture.completedFuture(null);
        } catch (Exception e) {
            log.error("异步记录操作日志失败", e);
            return CompletableFuture.failedFuture(e);
        }
    }

    /**
     * 构建操作日志实体
     */
    private SysLogOperation buildOperationLog(@NotNull HttpServletRequest request, Object[] args) throws IOException {
      //  Long userId = SecurityContextHolder.getUserId();
     //   System.out.println("userIdLog:"+userId);
        SysLogOperation operation = new SysLogOperation();
        
        // 记录请求信息
        operation.setType(1);
        operation.setMode(request.getMethod());
        operation.setUrl(request.getRequestURI());
        operation.setModel(resolveModuleName(request.getRequestURI()));
        operation.setIp(request.getRemoteAddr());
        operation.setTerminal(request.getHeader("terminal"));
        operation.setCreateDate(System.currentTimeMillis());
   //     operation.setDeleted(0);
        //operation.setUserId(userId);

        // 处理请求参数
        JSONObject params = new JSONObject();
        request.getParameterMap().forEach((key, value) -> 
            params.put(key, String.join(",", value))
        );

        if (args != null) {
            JSONArray jsonArray = new JSONArray(Arrays.stream(args).toList());
            System.out.println("jsonArray:"+jsonArray);
            params.put("args", jsonArray);
            for (Object arg : args) {
                System.out.println("arg:"+arg);
            }
        }

        Map<String, String[]> parameterMap = request.getParameterMap();
    for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
        String key = entry.getKey();
        String[] values = entry.getValue();
        System.out.println("Key: " + key + ", Values: " + Arrays.toString(values));
    }
        // 处理请求体
        ServletInputStream inputStream = request.getInputStream();
        System.out.println("inputStream.available()"+inputStream.available());
        System.out.println("inputStream.available()"+inputStream.isReady());
        if (inputStream.available() > 0) {
            BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(request);
            byte[] requestBody = bufferedRequest.requestBody;
            if (requestBody.length > 0) {
                String bodyStr = new String(requestBody, StandardCharsets.UTF_8);
                operation.setData(parseRequestBody(bodyStr));
            }
        } else {
            System.out.println("requestBody.length == 0");
            operation.setData(params.toJSONString());
        }
        System.out.println("SecurityContextHolder.getContext().getAuthentication()");
        System.out.println(SecurityContextHolder.getContext().getAuthentication());
        // 设置用户信息
        if (SecurityContextHolder.getContext().getAuthentication() != null) {
            System.out.println("SecurityContextHolder.getContext().getAuthentication() != null");
            LoginUser loginUser = SecurityUtils.getLoginUser();
            if (loginUser != null) {
                operation.setUserId(loginUser.getId());
                operation.setAccount(loginUser.getUsername());
                operation.setOrganId(loginUser.getOrganId());
            }
        }

        return operation;
    }

    /**
     * 解析请求体
     */
    private String parseRequestBody(String bodyStr) {
        if (JSONUtil.isTypeJSONArray(bodyStr)) {
            return JSON.parseArray(bodyStr).toJSONString();
        } else {
            return JSONObject.parseObject(bodyStr).toJSONString();
        }
    }

    /**
     * 根据请求路径解析模块名称
     */
    private String resolveModuleName(String requestURI) {
        if (requestURI == null) return "系统";

        if (requestURI.startsWith("/sys/user")) {
            return "用户管理";
        } else if (requestURI.startsWith("/sys/role")) {
            return "角色管理";
        } else if (requestURI.startsWith("/sys/menu")) {
            return "菜单管理";
        } else if (requestURI.startsWith("/sys/dept")) {
            return "部门管理";
        } else if (requestURI.startsWith("/auth")) {
            return "授权管理";
        } else if (requestURI.startsWith("/sms")) {
            return "短信管理";
        } else {
            return "系统";
        }
    }
}